home *** CD-ROM | disk | FTP | other *** search
- /* implementation file for apply function for sorted list data
- structure. implemented as an AVL tree. */
-
- #include "sortlist.h"
- #include "slintrnl.h"
-
- typedef struct
- {
- /* apply function */
- int (*apply)(void *elem, void *param);
- /* second parameter to apply function */
- void *param;
- /* which branch to do first */
- int first_branch;
- /* starting key (may be null) */
- void *start_key;
- /* key - element compare function */
- int (*k_e_compare)(const void *key, const void *elem);
- }
- APPLY_PARAM;
-
- /* visit each element in subtree after given start */
- static int do_apply
- (
- /* subtree to traverse */
- void *tree,
- /* other parameters */
- APPLY_PARAM *ap
- )
- {
- int r;
-
- if (!tree)
- return(0);
-
- if (ap->start_key)
- {
- r = (*(ap->k_e_compare))(ap->start_key, ELEM_IN_NODE(tree));
- if (ap->first_branch == GREATER_BRANCH)
- r = -r;
- }
- else
- r = -1;
-
- if (r <= 0)
- {
- if (r < 0)
- r = do_apply(NODE(tree)->branch[ap->first_branch], ap);
- if (!r)
- r = (*(ap->apply))(ELEM_IN_NODE(tree), ap->param);
- if (r)
- return(r);
- }
- return(do_apply(NODE(tree)->branch[OTHER(ap->first_branch)], ap));
- }
-
- /* visit each element in the list in ascending or descending order.
- call a given function with the element being visited as a parameter.
- if the given function returns non-zero, the traversal is interrupted.
- returns the result of the last call to the given function, or 0 if
- no elements are visited */
- int apply_sort_list
- (
- /* sorted list to traverse */
- const SORT_LIST *sl,
- /* function to call. the first parameter is the element being
- visited. the second parameter is supplied below. this function
- can change element keys if and only if the next operation to
- be performed on the sorted list is a clear. */
- int (*apply)(void *elem, void *param),
- void *param,
- /* if this flag non-zero, list is traversed in ascending order,
- otherwise descending */
- int forward,
- /* key which indicates which element to start the traversal
- with. if forward flag set, start with least element greater
- than or equal to this key. if traversal is backward, start with
- the greatest element less than or equal to this key. if this
- parameter is null, all elements are traversed. */
- void *start_key
- )
- {
- APPLY_PARAM ap;
-
- ap.apply = apply;
- ap.param = param;
- ap.first_branch = forward ? LESS_BRANCH : GREATER_BRANCH;
- ap.start_key = start_key;
- ap.k_e_compare = sl->key_elem_compare;
-
- return(do_apply(sl->tree, &ap));
- }
-